﻿using System;
using System.Data;
using T.ServiceComponent.Log.SPI;
using T.FAS.Runtime.Metadata.Entity.DataModel;
using T.FAS.Runtime.Base.Entity;
using T.FAS.Runtime.DataAccess.SPI;
using Newtonsoft.Json;
using System.Collections.Generic;
using System.Net;

namespace T.FAS.Runtime.DataAccess.Common
{
    public class BigDataLog : LogBase
    {
        public const string APPCode = "FAS";
        public const string ModuleCode = "FASDAC";

        public BigDataLog()
        {
            LogClientTools.StartLog();
        }

        public override void Write(object obj, ExtLogInfo extLogInfo = null)
        {
            if (!ExecuteLogSetting.IsLog || !ExecuteLogSetting.IsLogNormal || obj == null) return;
            var currTime = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff");
            TrackLog traceLog = new TrackLog
            {
                ModuleCode = ModuleCode,
                AppCode = APPCode,
                UserID = UserUtil.GetCurrentUserID(),
                Context = JsonConvert.SerializeObject(obj, Setting),
                CreateTime = DateTime.Now,
                ServerIP = HostName,
                Ext1 = extLogInfo?.MetaDataCode,
                Ext10 = currTime,
                ExtColumnNames = $"Ext字段备注说明 ext1:元数据编号, ext10:当前时间",
            };
            traceLog.Ext10 = currTime;
            LogClientTools.Put(traceLog);
        }

        public override void WriteChangeLog(List<DataChangeLog> changeLogs, ExtLogInfo extLogInfo = null)
        {
            if (!ExecuteLogSetting.IsLog || !ExecuteLogSetting.IsLogChange) return;
            var currTime = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff");
            if (changeLogs != null)
            {
                foreach (var log in changeLogs)
                {
                    log.ServerIP = HostName;
                    log.Ext1 = extLogInfo?.MetaDataCode;
                    log.Ext10 = currTime;
                    log.ExtColumnNames = $"Ext字段备注说明 ext1:元数据编号, ext10:当前时间";
                    LogClientTools.Put(log);
                }
            }
        }

        public override void WriteError(Exception er, string msg = null, ExtLogInfo extLogInfo = null)
        {
            if (!ExecuteLogSetting.IsLog || !ExecuteLogSetting.IsLogError) return;
            var currTime = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff");
            ExceptionLog errLog = new ExceptionLog
            {
                AppCode = APPCode,
                ModuleCode = ModuleCode,
                ExpCode = "FAS-DAC-ErrorLog",
                ExpLevel = ErrorLevel.Error.ToString(),
                CreateTime = DateTime.Now,
                Context = msg,
                ExpType = "DAC",
                ExpStack = er.GetFullStackTrace(),
                ExpInfo = er.Message,
                InnerExpInfo = er.GetInnermostExceptionMsg(),
                UserID = UserUtil.GetCurrentUserID(),
                ServerIP = HostName,
                ExtColumnNames = $"Ext字段备注说明 ext1:元数据编号, ext10:当前时间",
            };

            errLog.Ext1 = extLogInfo?.MetaDataCode;
            errLog.Ext10 = currTime;
            LogClientTools.Put(errLog);
        }

        public override void WriteSQL(string sql, IDbDataParameter[] paras = null, SQLLogType type = SQLLogType.DQL, ExtLogInfo extLogInfo = null)
        {
            if (!ExecuteLogSetting.IsLog || !ExecuteLogSetting.IsLogSQL) return;
            var currTime = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff");
            SysActionLog sysLog = new SysActionLog
            {
                AppCode = APPCode,
                ModuleCode = ModuleCode,
                Action = type == SQLLogType.DQL ? "FAS-DAC-SQLLog-DQL" : "FAS-DAC-SQLLog-DML",
                CreateTime = DateTime.Now,
                Result = "success",
                Context = sql,
                UserID = UserUtil.GetCurrentUserID(),
                ServerIP = HostName,
                ExtColumnNames = $"Ext字段备注说明 ext1:元数据编号, ext10:当前时间, ext11:参数列表"
            };

            sysLog.Ext1 = extLogInfo?.MetaDataCode;
            sysLog.Ext10 = currTime;
            if (paras != null)
            {
                Dictionary<string, string> parDict = new Dictionary<string, string>();
                List<DbParmLog> dbParmLogs = new List<DbParmLog>();
                foreach (IDbDataParameter par in paras)
                {
                    if (par != null)
                    {
                        parDict[par.ParameterName] = par.Value?.ToString();
                    }
                    try
                    {
                        dbParmLogs.Add(new DbParmLog
                        {
                            Code = par.ParameterName,
                            Value = par.Value,
                            DbType = par.DbType.ToString(),
                            ValueType = par.Value?.GetType().Name,
                            ParamType = par.GetType().Name,
                        });
                    }
                    catch
                    {
                    }
                }
                sysLog.Ext11 = JsonConvert.SerializeObject(parDict);
                sysLog.Ext12 = JsonConvert.SerializeObject(dbParmLogs);
            }
            LogClientTools.Put(sysLog);
        }

        public override void WriteStateChangeLog(List<StateMachineChangedMsg> msgs, ExtLogInfo extLogInfo = null)
        {
            if (!ExecuteLogSetting.IsLog || !ExecuteLogSetting.IsLogState) return;
            var currTime = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff");
            if (msgs != null)
            {
                foreach (var msg in msgs)
                {
                    DataChangeLog dataChangeLog = new DataChangeLog
                    {
                        ModuleCode = ModuleCode,
                        AppCode = APPCode,
                        Action = msg.CDOCode,
                        BillID = msg.BillID,
                        Ext10 = msg.StateMachineID,
                        Ext11 = msg.StateMachineCode,
                        Ext12 = msg.ColKey,
                        Ext13 = msg.ColName,
                        Ext14 = msg.EventKey,
                        Ext15 = msg.EventName,
                        Ext16 = msg.FromState.Value.ToString(),
                        Ext17 = msg.FromStateName,
                        Ext18 = msg.ToState.ToString(),
                        Ext19 = msg.ToStateName,
                        ServerIP = HostName,
                        CreateTime = DateTime.Now,
                        Ext1 = extLogInfo?.MetaDataCode,
                        Ext20 = currTime,
                        ExtColumnNames = $"Ext字段备注说明 ext1:元数据编号, ext20:当前时间"
                    };
                    LogClientTools.Put(dataChangeLog);
                }
            }
        }

        /// <summary>
        /// DAC运行日志
        /// </summary>
        public override void CDOTraceLog(CompositeDataObject cdo, TRecord record, InjectionMethodType opType, string msg = null, object extObj = null)
        {
            if (!ExecuteLogSetting.IsLog || !ExecuteLogSetting.IsLogTrace) return;
            try
            {
                if (cdo == null || record == null) return;
                var pkVal = GetCDOPkValue(cdo, record)?.ToString();
                var currTime = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff");
                var traceInfo = new
                {
                    CurrentTime = currTime,
                    Msg = msg,
                    PkVal = pkVal,
                    OpType = opType.ToString(),
                };
                TrackLog traceLog = new TrackLog
                {
                    FuncID = cdo.Code,
                    DataKey = pkVal,
                    UserID = UserUtil.GetCurrentUserID(),
                    TraceInfo = JsonConvert.SerializeObject(traceInfo, Setting),
                    ServerIP = HostName
                };
                traceLog.Ext10 = currTime;
                if (extObj != null)
                    traceLog.Ext12 = JsonConvert.SerializeObject(extObj, Setting);
                LogClientTools.Put(traceLog);
            }
            catch (Exception e)
            {
                //LocalLogService.Write(e);
            }
        }

        private static string hostName = string.Empty;
        /// <summary>
        /// 主机名
        /// </summary>
        private string HostName
        {
            get
            {
                if (string.IsNullOrEmpty(hostName))
                    hostName = Dns.GetHostName();
                return hostName;
            }
        }
    }


    class DbParmLog
    {
        public string Code { get; set; }
        public object Value { get; set; }
        public string DbType { get; set; }
        public string ValueType { get; set; }
        public string ParamType { get; set; }
    }
}